package castle.defense.project;

import java.util.HashMap;
import java.util.LinkedList;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.Style;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;

/**
 * Basic graphics engine for rendering drawings and basic shaps on the screen.
 * 
 * @author Daniel Wasserman
 *
 */
public class GraphicsEngine {
	private static HashMap<Integer, BitmapDrawable> imageMap;
	private static HashMap<Integer, Bitmap> realMap;
	private static HashMap<Integer, Double> xScale, yScale;
	private static HashMap<Integer, Integer> type;
	private static LinkedList<Integer> indices;
	private static Paint paint, paint2;
	private static Bitmap backgroundtile, backgroundFull;
	//returns the ID:
	//type 1 = scale by y only for square, type 2 = scale by x and y
	public static void addImage(int index, Drawable d, double scaleX, double scaleY, int thisType) {
		BitmapDrawable bd = (BitmapDrawable)d;
		if(imageMap == null) {
			imageMap = new HashMap<Integer, BitmapDrawable>();
		}
		if(xScale==null) {
			yScale = new HashMap<Integer, Double>();
			xScale = new HashMap<Integer, Double>();
			indices = new LinkedList<Integer>();
			type = new HashMap<Integer, Integer>();
		}
		if(imageMap.containsKey(index))
			return;
		indices.add(index);
		imageMap.put(index, bd);
		xScale.put(index, scaleX);
		yScale.put(index, scaleY);
		type.put(index, thisType);
	}

	public static void addImage(int index, Drawable d) {
		BitmapDrawable bd = (BitmapDrawable)d;
		if(imageMap == null) {
			imageMap = new HashMap<Integer, BitmapDrawable>();
		}
		if(imageMap.containsKey(index))
			return;
		imageMap.put(index, bd);
	}
	public static Drawable getDrawable(int index) {
		return imageMap.get(index);
	}
	public static void setBackground(Resources res, int id) {
		backgroundtile = BitmapFactory.decodeResource(res, id);
	}
	public static void initialize() {
		if(backgroundtile == null) {
			return;
		}
		//pre-paint background:
		int w = backgroundtile.getWidth();
		int h = backgroundtile.getHeight();
		backgroundFull = Bitmap.createBitmap((int)(Math.ceil(PE.sizeX/w))*w, (int)(Math.ceil(PE.sizeY/h))*h, Bitmap.Config.RGB_565);
		Canvas backgroundCanvas = new Canvas(backgroundFull);
		for(int i = 0; i < PE.sizeX; i+=backgroundtile.getWidth()) {
			for(int j = 0; j < PE.sizeY; j+=backgroundtile.getHeight()) {
				backgroundCanvas.drawBitmap(backgroundtile, i, j, paint2);
			}
		}
		realMap = new HashMap<Integer, Bitmap>();
		if(indices!=null) {
			for(int i : indices) {
				int thisType = type.get(i);
				int xSize = (int)Math.round(PE.screenPercentY(xScale.get(i)));
				int ySize = (int)Math.round(PE.screenPercentY(yScale.get(i)));
				if(thisType == 1) {
					xSize = ySize;
				}
				Bitmap b = Bitmap.createBitmap(xSize, ySize, Bitmap.Config.ARGB_8888);
				Canvas c = new Canvas(b);
				c.drawColor(Color.TRANSPARENT);
				BitmapDrawable image = imageMap.get(i);
				image.setBounds(0, 0, xSize, ySize);
				image.draw(c);
				realMap.put(i, b);
			}
		}
	}
	public static void drawBackground(Canvas c) {
		if(backgroundFull!=null)
			c.drawBitmap(backgroundFull, 0, 0, paint2);
	}
	public static void drawGameOverText(Canvas c) {
		paint.setTextSize((float)((PE.screenPercentX(10) + PE.screenPercentY(10))/2));
		drawText(c,"Game Over",PE.screenPercentX(50),PE.screenPercentY(35),paint);
		//10-pixel buffer
		drawText(c,String.format("Score: %d",Score.score),PE.screenPercentX(50), PE.screenPercentY(35)+paint.getTextSize()+10,paint);
	}
	public static void drawText(Canvas c, String text, double x, double y, Paint p) {
		c.drawText(text,(float)x,(float)y,p);
	}
	public static void drawText(Canvas c, String text, double x, double y, double perc) {
		initializePaint();
		paint.setTextSize((float)((PE.screenPercentX(perc) + PE.screenPercentY(perc))/2));
		drawText(c,text,x,y,paint);
	}
	public static void initializePaint() {
		if(paint==null) {
			paint = new Paint();
			paint.setColor(Color.BLACK);
			paint.setStyle(Style.FILL_AND_STROKE);
			paint.setTextAlign(Align.CENTER);
			paint.setFakeBoldText(true);

			paint2 = new Paint();
			paint2.setXfermode(null);
		}
	}
	public static void drawOval(Canvas c, PhysicsPoint p, double r) {
		initializePaint();
		c.drawOval(PE.screenRegion(p.x-r, p.y-r, p.x+r, p.y+r), paint);
	}
	public static void drawOval(Canvas c, PhysicsPoint p, double r, Paint paint) {
		c.drawOval(PE.screenRegion(p.x-r, p.y-r, p.x+r, p.y+r), paint);
	}
	public static void drawOval(Canvas c, PhysicsPoint p, double r, int color) {
		initializePaint();
		paint.setColor(color);
		c.drawOval(PE.screenRegion(p.x-r, p.y-r, p.x+r, p.y+r),paint);
	}
	public static void draw(Canvas c, int image, double left, double top)
	{
		float t = PE.toScreenY(top);
		Bitmap b = realMap.get(image);
		c.drawBitmap(b, (float)left, t, paint2);
		
//		BitmapDrawable b = realMap.get(image);
//		b.setBounds((int)Math.round(left),(int)Math.round(t),(int)Math.round(left+b.getBitmap().getWidth()),(int)Math.round(t+b.getBitmap().getHeight()));
//		b.draw(c);
	}
	public static void drawHealthBar(Canvas c, double x1, double y1, double x2, double y2, double health, double totalhealth) {
		initializePaint();
		paint.setColor(Color.RED);
		c.drawRect(PE.screenRegion(x1, y1, x2, y2), paint);
		paint.setColor(Color.GREEN);
		double w = x2-x1;
		c.drawRect(PE.screenRegion(x1, y1, x1+w*(health/totalhealth), y2), paint);
		paint.setColor(Color.BLACK);
	}
}
